﻿using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Single.Json
{
    /// <summary>
    /// 自定义序列化解析器
    /// </summary>
    public class JsonCustomContractResolver : DefaultContractResolver
    {
        string[] retain = null;
        string[] ignore = null;
        IDictionary<string, string> turns = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="retain">保留属性</param>
        /// <param name="ignore">忽略属性</param>
        /// <param name="turns">要转换的属性</param>
        public JsonCustomContractResolver(string[] retain = null, string[] ignore = null, IDictionary<string, string> turns = null)
        {
            // 指定要序列化属性的清单
            this.retain = retain;
            // 指定要忽略属性的清单
            this.ignore = ignore;
            // 指定要转换名称属性的清单
            this.turns = turns;
        }

        /// <summary>
        /// 重写属性创建函数
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <param name="memberSerialization">成员序列化对象</param>
        /// <returns>成员属性集合</returns>
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            List<JsonProperty> list = base.CreateProperties(type, memberSerialization).ToList();

            if (retain != null)
            {
                // 只保留清单有列出的属性
                list = list.Where(p => retain.Contains(p.PropertyName)).ToList();
            }

            if (ignore != null)
            {
                // 只保留清单有列出的属性
                list = list.Where(p => !ignore.Contains(p.PropertyName)).ToList();
            }

            if (turns != null)
            {
                // 修改需要修改名称的属性
                foreach (var turn in turns)
                {
                    list.ForEach(new Action<JsonProperty>((m) =>
                    {
                        if (m.PropertyName == turn.Key)
                        {
                            m.PropertyName = turn.Value;
                        }
                    }));
                }
            }

            return list;
        }
    }
}
